import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';

import '../config/env_config.dart';
import '../core/network_interceptor.dart';
import '../core/network_request.dart';
import '../core/network_response.dart';
import '../core/network_response_code.dart';

/// 自定义解析和请求头处理
class CustomParsing extends NetworkInterceptor {
  @override
  int get priority => 4;

  @override
  Future<void> willSend(RequestOptions options,
      RequestInterceptorHandler handler, TargetType target) async {
    /// 请求头合并
    final headers = HMNetworkConfig.host.globalHeaders.headers;
    options.headers = {...headers, ...options.headers};
    handler.next(options);
  }

  /// 请求遇到错误
  @override
  void didError(
    DioException err,
    ErrorInterceptorHandler handler,
    TargetType target,
  ) {
    var exception = err;

    /// 401
    if (HttpStatus.unauthorized == err.response?.statusCode) {
      const code = ResponseCode.invalidToken;
      final message = code.handleMessage('Token invalid or expired');
      code.onEvent(message, null);
      final error = NetworkException(
        code: code.code,
        message: message,
        data: null,
      );
      exception = DioException(
        requestOptions: err.requestOptions,
        response: err.response,
        type: err.type,
        stackTrace: err.stackTrace,
        message: err.message,
        error: error,
      );
    }
    super.didError(exception, handler, target);
  }

  @override
  void didReceive(Response response, ResponseInterceptorHandler handler,
      TargetType target) {
    response.data = _handleResponse(response);
    handler.next(response);
  }

  /// 处理响应结果
  ResponseResult<T> _handleResponse<T>(Response<dynamic> response) {
    final result = ResponseResult<T>();
    try {
      /// 请求成功
      if ([HttpStatus.ok, HttpStatus.created].contains(response.statusCode)) {
        /// 字典格式
        if (response.data is Map<String, dynamic>) {
          final dataMap = response.data as Map<String, dynamic>;

          /// 固定格式的字典
          if (dataMap.containsKey(MappingKey.code) &&
              dataMap.containsKey(MappingKey.data)) {
            final codeValue = dataMap[MappingKey.code].toString();
            final code = ResponseCode.rawValue(codeValue);
            dynamic data = dataMap[MappingKey.data];

            /// 处理异常场景
            if (code != ResponseCode.success &&
                code != ResponseCode.specialSuccess) {
              final message = dataMap[MappingKey.description];

              /// 全局错误码处理
              code.onEvent(message, data);
              throw NetworkException(
                code: codeValue,
                message: code.handleMessage(message),
                data: data,
              );
            } else {
              /// 处理正确结果
              if (data is Map<String, dynamic>) {
                result.dataMap = data;
              } else if (data is List) {
                result.dataList = data;
              }
              result.data = data;

              /// json转换为model
              if (data != null &&
                  response.requestOptions.extra[MappingKey.transformer]
                      is TransformValue) {
                final mapping = response.requestOptions
                    .extra[MappingKey.transformer] as TransformValue<T>;
                result.data = mapping(data);
              }
              return result;
            }
          } else {
            /// 任意格式字典
            result.data = response.data;
            result.dataMap = dataMap;

            /// json转换为model
            if (response.requestOptions.extra[MappingKey.transformer]
                is TransformValue) {
              final mapping = response.requestOptions
                  .extra[MappingKey.transformer] as TransformValue<T>;
              result.data = mapping(dataMap);
            }
            return result;
          }
        } else if (response.data is String) {
          /// 字符串格式
          result.data = response.data;
          return result;
        } else if (response.data is ResponseBody &&
            response.data.stream is Stream) {
          /// 数据流
          TransformValue? mapper;
          if (response.requestOptions.extra[MappingKey.transformer]
              is TransformValue) {
            mapper = response.requestOptions.extra[MappingKey.transformer]
                as TransformValue;
          }
          result.stream = _transform(response.data.stream as Stream?, mapper);
          return result;
        } else {
          /// 其它格式，暂不解析
          result.data = response.data;
          return result;
        }
      } else {
        /// 处理异常场景

        /// 请求失败(状态码不是200、201)
        throw NetworkException.system();
      }
    } catch (error) {
      /// 处理异常
      if (error is NetworkException) {
        result.exception = error;
      }
      return result;
    }
  }

  Stream? _transform(Stream? stream, TransformValue? transformer) {
    StreamTransformer<Uint8List, List<int>> unit8Transformer =
        StreamTransformer.fromHandlers(
      handleData: (data, sink) {
        sink.add(List<int>.from(data));
      },
    );

    final result = stream
        ?.transform(unit8Transformer)
        .transform(const Utf8Decoder())
        // .transform(const LineSplitter())
        .map((text) {
      final result = transformer?.call(text);
      if (result != null) {
        return result;
      } else {
        return text;
      }
    });
    return result;
  }
}
